package sg.edu.nus.iss.vmcs.customer;

import java.awt.*;
import java.awt.event.*;

import sg.edu.nus.iss.vmcs.ui.awt.PanelAdapter;
import sg.edu.nus.iss.vmcs.util.LabelledDisplay;
import sg.edu.nus.iss.vmcs.util.WarningDisplay;

/**
* CustomerPanel inherits from Dialog class from Abstract Tool Kit library class
* of Java. This class represents the customer panel which enables to insert coins, select
* brands, terminate transaction. It also provides following display functions:
* 1 display total money inserted;
* 2 indicate coin not valid;
* 3 indicate no change available;
* 4 display the value of the change to be collected;
* 5 display an icon representing the dispensed drink.
* 
* @version 3.0 29/11/2011
* @author  Team 7S - SE19
*/

public class CustomerPanel extends Dialog {

	private static final String TITLE = "VMCS - Customer Panel";

/**
 * Active Color
 */	
	public final static Color ACT_COLOR = Color.white;
	
	private TransactionController transCtrl;
	
	private CoinInputBox          coinInput;
	private DrinkSelectionBox     drinkInput;
	
	private LabelledDisplay 	  moneyInserted;
	private LabelledDisplay 	  collectCoin;
	private LabelledDisplay 	  collectCan;
	private WarningDisplay 		  invalidCoin;
	private WarningDisplay 		  noChangeAvail;
	private Button                terminateBtn;

/**
 * This constructor creates an instance of the Customer Panel. 
 * It further creates Invalid Coin Display,No Change Available Display, 
 * Refund/Change Tray Display, Total Money Inserted Display, Coin Input Box, 
 * Drink Selection Box, Can Collection Box and Terminate Button. It receives
 * the reference for transaction controller object as a parameter.
 * @param fr Frame 
 * @param tCtrl Transaction Controller
 * @see TransactionController
 */	
	public CustomerPanel(Frame fr, TransactionController tCtrl) {
		super(fr, TITLE, false);

		transCtrl = tCtrl;

		Label lb = new Label("VIMTO Soft Drink Dispenser");
		lb.setFont(new Font("Helvetica", Font.BOLD, 24));
		lb.setAlignment(Label.CENTER);
		
		invalidCoin   = new WarningDisplay("Invalid Coin");
		noChangeAvail = new WarningDisplay("No Change Available");

		moneyInserted = new LabelledDisplay("Total Money Inserted:", 10, LabelledDisplay.DEFAULT);
		moneyInserted.setEditable(false);
		moneyInserted.setTextBackground(0,0,0);
		moneyInserted.setTextForeground(255,255,255);
		
		collectCoin   = new LabelledDisplay("Collect Coins:   ",  5, LabelledDisplay.FLOW);
		collectCoin.setEditable(false);
		collectCoin.setTextBackground(0,0,0);
		collectCoin.setTextForeground(255,255,255);
		
		collectCan    = new LabelledDisplay("Collect Can Here:", 10, LabelledDisplay.FLOW);
		collectCan.setEditable(false);
		collectCan.setTextBackground(0,0,0);
		collectCan.setTextForeground(255,255,255);

		this.initializeCoins(); 
		this.initializeDrinks(); 

		PanelAdapter tl1 = new PanelAdapter();
		tl1.add(lb);

		PanelAdapter tl3 = new PanelAdapter();
		tl3.setLayout(new GridLayout(3,1));
		coinInput.setActive(false);
		tl3.add(coinInput);
		tl3.add(invalidCoin);
		tl3.add(moneyInserted.getLabelledDisplay());

		PanelAdapter tp1 = new PanelAdapter();
		tp1.setLayout(new GridLayout(1,1));
		tp1.add(drinkInput);

		terminateBtn = new Button("Terminate and Return Cash");
		terminateBtn.setFont(new Font("Helvetica", Font.BOLD, 12));
		terminateBtn.setBackground(ACT_COLOR);
		Panel tp3 = new Panel();
		tp3.setLayout(new FlowLayout());
		tp3.add(terminateBtn);
		terminateBtn.addActionListener(new TerminateButtonListener(tCtrl));
		
		Panel tp2 = new Panel();
		tp2.setLayout(new GridLayout(2,1));
		tp2.add(noChangeAvail);
		tp2.add(tp3);
		
		PanelAdapter tp4 = new PanelAdapter();
		tp4.setLayout(new BorderLayout());
		tp4.add("North", collectCoin.getLabelledDisplay());
		tp4.add("Center",collectCan.getLabelledDisplay());

		PanelAdapter tpn = new PanelAdapter();
		tpn.setLayout(new BorderLayout());
		tpn.add("North", (Panel)tl1);
		tpn.add("Center", (Panel)tl3);
		tpn.add("South", (Panel)tp1);
		
		PanelAdapter tpc = new PanelAdapter();
		tpc.setLayout(new GridLayout(2, 1));
		tpc.add(tp2);
		tpc.add((Panel)tp4);

		this.setLayout(new BorderLayout());
		this.add("North", tpn);
		this.add("Center", tpc);
		pack();

		setLocation(200,100);
		
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				transCtrl.closeDown();
			}
		});
	}

/**
 * Display the Customer Panel. This will be achieved by displaying the frame of 
 * the panel and then sending messages to its constituent objects instructing 
 * them to display themselves.
 */	
	public void display() {
		this.setVisible(true);
	}

/**
 * This operation remove the Customer Panel from the display. 
 */	
	public void closeDown() {
		dispose();
	}	

	private void initializeCoins () {
		CoinReceiver coinRcv = transCtrl.getCoinReceiver();
		coinInput = new CoinInputBox(this, coinRcv);
		coinInput.addListener();
	}
	
	private void initializeDrinks() {
		drinkInput = new DrinkSelectionBox(this, transCtrl);
		drinkInput.setAction();
	}

/**
 * This operation returns reference for CoinInputBox object
 * @return CoinInput
 */	
	public CoinInputBox getCoinInput() {
		return coinInput;
	}

/**
 * This operation returns the LabelledDisplay (Drinks Can).
 * @return collecCan
 */	
	public LabelledDisplay getCollectCan() {
		return collectCan;
	}

/**
 * This operation returns the LabelledDisplay (Coin).
 * @return collectCoin
 */	
	public LabelledDisplay getCollectCoin() {
		return collectCoin;
	}

/**
 * This operation returns DrinkSelectionBox.
 * @return DrinkSelectionBox
 */	
	public DrinkSelectionBox getDrinkInput() {
		return drinkInput;
	}

/**
 * This operation returns WarningDisplay object to display.
 * @return WarningDisplay
 */	
	public WarningDisplay getInvalidCoin() {
		return invalidCoin;
	}

/**
 * This operation returns the LabelledDisplay (Money Inserted).
 * @return moneyInserted
 */	
	public LabelledDisplay getMoneyInserted() {
		return moneyInserted;
	}

/**
 * This operation returns the Warning Display (No Change Available)
 * @return WarningDisplay
 */	
	public WarningDisplay getNoChangeAvail() {
		return noChangeAvail;
	}

	public Button getTerminateBtn() {
		return terminateBtn;
	}
}
